/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import com.jnetx.javax.sip.util.ByteArrayUtil;

import java.text.ParseException;

/**
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public abstract class ParametrizedHeaderParserBase<T extends ParametrizedHeaderBase> extends HeaderParserBase<T> {
    protected void parseParameters(T header, byte[] data, int start, int end) throws ParseException {
        parseParameters(header, data, start, end, ';');
    }

    protected void parseParameters(T header, byte[] data, int start, int end, char delimiter) throws ParseException {
        int pos = start, prevPos = data[start] == delimiter ? start : start - 1;
        while ((pos = ByteArrayUtil.firstOccurence(data, delimiter, prevPos + 1, end)) != -1 || prevPos < end) {
            if (pos == -1) pos = end;
            int startOfName = ByteArrayUtil.firstMissing(data, ' ', prevPos + 1, pos);
            final int index = ByteArrayUtil.firstOccurence(data, '=', startOfName, pos);
            final String name, value;
            if (index != -1) {
                int startOfValue = ByteArrayUtil.firstMissing(data, ' ', index + 1, pos);
                int endOfValue = pos;
                if (startOfValue != -1) {
                    endOfValue = ByteArrayUtil.lastMissing(data, ' ', startOfValue, endOfValue);
//                    final byte startChar = data[startOfValue];
//                    final byte endChar = data[endOfValue];
//                    if ((startChar == '"' && endChar == '"') || (startChar == '\'' && endChar == '\''))
//                        startOfValue++;
//                    else
                    endOfValue++;
                }
                name = new String(data, startOfName, index - startOfName);
                value = new String(data, startOfValue, endOfValue - startOfValue);
            } else {
                name = new String(data, startOfName, pos - startOfName);
                value = null;
            }
            if (!parseSpecificParameter(header, name, value))
                header.setRawParameter(name, value);
            prevPos = pos;
        }
    }

    /**
     * This procedure should be overriden by those parsers who want parse some parameters in a specific way.
     *
     * @param header the header object.
     * @param name   the name of a parameter.
     * @param value  the value of a parameter including parentheses.
     * @return true if the parameter has been parsed and no other actions ahould be taken, false otherwise.
     * @throws ParseException
     */
    protected boolean parseSpecificParameter(T header, String name, String value) throws ParseException {
        return false;
    }
}
/*
 * $Log$
 */